#!/bin/bash

# 资产管理系统 - 一键部署脚本
# 版本: 1.0
# 作者: Asset Management Team
# 日期: 2025-08-07

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 配置变量
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
APP_DIR="/opt/asset-management"
BACKUP_DIR="/opt/asset_backups"
ENV_FILE="$PROJECT_DIR/.env"

# 日志函数
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 错误处理
error_exit() {
    log_error "$1"
    exit 1
}

# 检查依赖
check_dependencies() {
    log_info "检查系统依赖..."
    
    # 检查Docker
    if ! command -v docker &> /dev/null; then
        error_exit "Docker未安装，请先运行 ./scripts/setup_centos7.sh"
    fi
    
    # 检查Docker Compose
    if ! command -v docker-compose &> /dev/null; then
        error_exit "Docker Compose未安装，请先运行 ./scripts/setup_centos7.sh"
    fi
    
    # 检查Docker服务状态
    if ! systemctl is-active --quiet docker; then
        log_info "启动Docker服务..."
        sudo systemctl start docker
    fi
    
    log_success "依赖检查通过"
}

# 生成随机密码
generate_password() {
    openssl rand -base64 32 | tr -d "=+/" | cut -c1-25
}

# 创建环境配置文件
create_env_file() {
    log_info "创建环境配置文件..."
    
    if [[ -f "$ENV_FILE" ]]; then
        log_warning "环境配置文件已存在，是否覆盖？(y/N)"
        read -r response
        if [[ ! "$response" =~ ^[Yy]$ ]]; then
            log_info "跳过环境配置文件创建"
            return 0
        fi
    fi
    
    # 生成随机密码
    local secret_key=$(generate_password)$(generate_password)
    local grafana_password=$(generate_password)
    
    # 获取服务器IP
    local server_ip=$(curl -s ifconfig.me || echo "localhost")
    
    # 创建.env文件
    cat > "$ENV_FILE" << EOF
# 数据库配置
DB_NAME=asset_db
DB_USER=root
DB_PASSWORD=123456
DB_ROOT_PASSWORD=123456

# Django配置
SECRET_KEY=$secret_key
DEBUG=False
ALLOWED_HOSTS=localhost,127.0.0.1,$server_ip

# 邮件配置（请根据实际情况修改）
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_USER=your-email@gmail.com
EMAIL_PASSWORD=your-email-password

# 监控配置
GRAFANA_USER=admin
GRAFANA_PASSWORD=$grafana_password

# SSL配置
SSL_CERT_PATH=/etc/nginx/ssl/cert.pem
SSL_KEY_PATH=/etc/nginx/ssl/key.pem

# 备份配置
BACKUP_PATH=$BACKUP_DIR
BACKUP_RETENTION_DAYS=30

# 时区配置
TZ=Asia/Shanghai
EOF
    
    # 设置文件权限
    chmod 600 "$ENV_FILE"
    
    log_success "环境配置文件创建完成"
    log_info "数据库密码: 123456"
    log_info "Grafana密码: $grafana_password"
    log_warning "请妥善保存这些密码！"
}

# 复制项目文件
copy_project_files() {
    log_info "复制项目文件到部署目录..."
    
    # 创建部署目录
    sudo mkdir -p "$APP_DIR"
    
    # 复制项目文件
    sudo cp -r "$PROJECT_DIR"/* "$APP_DIR/"
    
    # 设置权限
    sudo chown -R asset:asset "$APP_DIR"
    
    log_success "项目文件复制完成"
}

# 构建Docker镜像
build_images() {
    log_info "构建Docker镜像..."
    
    cd "$APP_DIR"
    
    # 构建应用镜像
    sudo -u asset docker-compose build --no-cache
    
    log_success "Docker镜像构建完成"
}

# 启动服务
start_services() {
    log_info "启动Docker服务..."
    
    cd "$APP_DIR"
    
    # 启动服务
    sudo -u asset docker-compose up -d
    
    # 等待服务启动
    log_info "等待服务启动..."
    sleep 30
    
    log_success "Docker服务启动完成"
}

# 数据库初始化
init_database() {
    log_info "初始化数据库..."
    
    cd "$APP_DIR"
    
    # 等待数据库启动
    log_info "等待数据库启动..."
    local max_attempts=30
    local attempt=1
    
    while [[ $attempt -le $max_attempts ]]; do
        if sudo -u asset docker-compose exec -T db mysql -u root -p123456 -e "SELECT 1" &>/dev/null; then
            break
        fi
        log_info "等待数据库启动... ($attempt/$max_attempts)"
        sleep 10
        ((attempt++))
    done
    
    if [[ $attempt -gt $max_attempts ]]; then
        error_exit "数据库启动超时"
    fi
    
    # 执行数据库迁移
    log_info "执行数据库迁移..."
    sudo -u asset docker-compose exec -T web python manage.py migrate
    
    # 收集静态文件
    log_info "收集静态文件..."
    sudo -u asset docker-compose exec -T web python manage.py collectstatic --noinput
    
    # 创建超级用户
    log_info "创建管理员账户..."
    sudo -u asset docker-compose exec -T web python manage.py shell << 'EOF'
from django.contrib.auth.models import User
if not User.objects.filter(username='admin').exists():
    User.objects.create_superuser('admin', 'admin@example.com', 'admin123')
    print("管理员账户创建成功")
else:
    print("管理员账户已存在")
EOF
    
    # 初始化系统参数
    log_info "初始化系统参数..."
    sudo -u asset docker-compose exec -T web python manage.py init_system_params
    
    log_success "数据库初始化完成"
}

# 健康检查
health_check() {
    log_info "执行健康检查..."
    
    cd "$APP_DIR"
    
    # 检查容器状态
    local containers=("asset_nginx" "asset_web" "asset_db" "asset_redis")
    
    for container in "${containers[@]}"; do
        if sudo -u asset docker ps --format "table {{.Names}}\t{{.Status}}" | grep -q "$container.*Up"; then
            log_success "容器 $container 运行正常"
        else
            log_error "容器 $container 运行异常"
            sudo -u asset docker logs "$container" --tail 20
        fi
    done
    
    # 检查Web服务
    local max_attempts=10
    local attempt=1
    
    while [[ $attempt -le $max_attempts ]]; do
        if curl -s -o /dev/null -w "%{http_code}" http://localhost/health/ | grep -q "200"; then
            log_success "Web服务健康检查通过"
            break
        fi
        log_info "等待Web服务启动... ($attempt/$max_attempts)"
        sleep 10
        ((attempt++))
    done
    
    if [[ $attempt -gt $max_attempts ]]; then
        log_warning "Web服务健康检查超时，请检查日志"
    fi
}

# 创建备份脚本
create_backup_script() {
    log_info "创建备份脚本..."
    
    sudo mkdir -p "$BACKUP_DIR"
    
    cat > /tmp/backup.sh << 'EOF'
#!/bin/bash
# 自动备份脚本

BACKUP_DIR="/opt/asset_backups"
DATE=$(date +%Y%m%d_%H%M%S)
APP_DIR="/opt/asset-management"

# 创建备份目录
mkdir -p "$BACKUP_DIR/$DATE"

# 备份数据库
cd "$APP_DIR"
docker-compose exec -T db mysqldump -u root -p123456 asset_db > "$BACKUP_DIR/$DATE/database.sql"

# 备份媒体文件
docker cp asset_web:/app/media "$BACKUP_DIR/$DATE/"

# 压缩备份
cd "$BACKUP_DIR"
tar -czf "backup_$DATE.tar.gz" "$DATE"
rm -rf "$DATE"

# 清理旧备份（保留30天）
find "$BACKUP_DIR" -name "backup_*.tar.gz" -mtime +30 -delete

echo "备份完成: backup_$DATE.tar.gz"
EOF
    
    sudo mv /tmp/backup.sh /usr/local/bin/asset_backup.sh
    sudo chmod +x /usr/local/bin/asset_backup.sh
    
    # 添加定时任务
    (sudo crontab -l 2>/dev/null; echo "0 2 * * * /usr/local/bin/asset_backup.sh") | sudo crontab -
    
    log_success "备份脚本创建完成"
}

# 显示部署信息
show_deployment_info() {
    local server_ip=$(curl -s ifconfig.me || echo "localhost")
    
    echo
    log_success "=== 部署完成 ==="
    echo
    log_info "访问地址:"
    log_info "  HTTP:  http://$server_ip"
    log_info "  HTTPS: https://$server_ip"
    echo
    log_info "管理员账户:"
    log_info "  用户名: admin"
    log_info "  密码:   admin123"
    echo
    log_info "监控面板:"
    log_info "  Grafana: http://$server_ip:3000"
    log_info "  用户名: admin"
    log_info "  密码: $(grep GRAFANA_PASSWORD "$ENV_FILE" | cut -d= -f2)"
    echo
    log_info "常用命令:"
    log_info "  查看服务状态: cd $APP_DIR && docker-compose ps"
    log_info "  查看日志:     cd $APP_DIR && docker-compose logs -f"
    log_info "  重启服务:     cd $APP_DIR && docker-compose restart"
    log_info "  停止服务:     cd $APP_DIR && docker-compose down"
    echo
    log_info "备份命令:"
    log_info "  手动备份:     /usr/local/bin/asset_backup.sh"
    log_info "  备份目录:     $BACKUP_DIR"
    echo
    log_warning "重要提醒:"
    log_warning "1. 请修改默认管理员密码"
    log_warning "2. 请配置邮件服务器设置"
    log_warning "3. 生产环境请使用正式SSL证书"
    log_warning "4. 请定期检查系统日志和备份"
    echo
}

# 回滚函数
rollback() {
    log_warning "部署失败，开始回滚..."
    
    cd "$APP_DIR" 2>/dev/null || return
    
    # 停止服务
    sudo -u asset docker-compose down 2>/dev/null || true
    
    # 清理镜像
    sudo -u asset docker system prune -f 2>/dev/null || true
    
    log_info "回滚完成"
}

# 信号处理
trap rollback ERR

# 主函数
main() {
    log_info "开始部署资产管理系统..."
    log_info "脚本版本: 1.0"
    log_info "执行时间: $(date)"
    echo
    
    # 检查是否为root用户
    if [[ $EUID -eq 0 ]]; then
        error_exit "请不要使用root用户运行此脚本"
    fi
    
    # 执行部署步骤
    check_dependencies
    create_env_file
    copy_project_files
    build_images
    start_services
    init_database
    health_check
    create_backup_script
    show_deployment_info
    
    log_success "部署完成！"
}

# 执行主函数
main "$@"